#include <stdio.h>
#include "_public.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "/home/lzb/today/c/niuer/data_struct/project/seq_stack/stack.h"
// #include "stack.h"

// 采用顺序栈来解决栈溢出的问题
int To_suffix_expression(char *str, int len);

int main (void)
{
    // char symbol[]={'(','*','/','+','-',')','\0'};


    // char ss[]="5+ 25 *(3+ 10/2-2)*1+40";
    // char ss[]="5+ 25 *(3+ 10/0-2)-5+40";
    // char ss[]="5+ 2*(2500 *(3+ 10/2-2)-5)+40";
    // char ss[]="5+ 2500 *(3+ 10/2-2)-5)+40";
    // char ss[]="5+ 25 *(3+ 10/2-2*2)+20+40";
    // char ss[]="2 +5*5-8 +55  -70/5 +5";
    // printf("%s\n",symbol);

    char ss[70];
    memset(ss,0,sizeof(ss));
    if(s_gets(ss,sizeof(ss))==NULL)
    {
        printf("输入出错\n");
        return -1;
    }
    delete_space(ss,strlen(ss));
    // printf("%s\n",ss);
    int len=strlen(ss);
    To_suffix_expression(ss,len);
    return 0;
}

int To_suffix_expression(char *str,int len)
{
    printf("中缀表达式为：%s\n",str);
    // 判断输入的字符串（算术表达式）是否合法
    if(!is_legal_input(str))
    {
        printf("这是一个非法的算术表达式\n");
        // return -1;
        exit(1);
    }

    // 判断输入的括号是否匹配
    if(!parentheses_match(str,len))
    {
        printf("您输入的括号不匹配\n");
        exit(1);
    }


    Stack *ps2=(Stack *)malloc(sizeof(Stack));      // 后缀表达式求值中用来存放操作数的链栈
    
    A_Stack *aps=(A_Stack *)malloc(sizeof(A_Stack));        // 采用顺序栈来存取操作符

    Queue *pqueue=(Queue *)malloc(sizeof(Queue));       //  队列

    // printf("Aaa\n");
    init_queue(pqueue);
    // init_stack(ps1);
    init_stack(ps2);
    A_init_stack(aps);

    char temp[10];      // 一个临时数组
    // 中缀转后缀
    for(int i=0;i<len;i++)
    {
        memset(temp,0,sizeof(temp));
        // 将数字暂存于一个字符数组中，再转换为int
        if(isdigit(str[i]))
        {
            int j=0;
            int number;
            while(isdigit(str[i]))      // 直到遇到非数字字符结束
            {
                temp[j++]=str[i++];
            }
            i=i-1;  // 因为最外层for循环会将i加一
            number=atoi(temp);
            // 操作数直接加入队列
            add_numbers(pqueue,number);
        }
        else        // 操作符
        {
            if(A_is_empty_stack(aps))   // 操作符栈为空，直接压栈
                A_push(aps,str[i]);
            else
            {
                switch (str[i])     // 对操作符分情况处理
                {
                case '(':
                    A_push(aps,str[i]);     // 左括号直接压栈
                    break;
                case ')':
                    A_pop_all(aps,pqueue);      // 右括号出栈直到将左括号出栈
                    // printf("i=%d\n",i);
                    break;
                default:        // 不是左右括号
                    if(aps->data[aps->top]=='(')    // 栈顶是左括号，直接压栈
                        A_push(aps,str[i]);
                    else
                        fun(aps,pqueue,str[i]);     // 栈顶不是左括号
                    break;
                }
            }
        }
        // dispaly_stack(ps1);
        A_dispaly_s(aps);
        dispay(pqueue);
    }

//     rogram received signal SIGABRT, Aborted.
// __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
// 49      ../sysdeps/unix/sysv/linux/raise.c: 没有那个文件或目录.


// 字符串操作完成，将栈内剩余符号出栈并加入队列
// 这样栈就为空，不需要再去清空
    while (!A_is_empty_stack(aps))
    {
        ElementType x=A_pop(aps);
        add(pqueue,x);
    }
    printf("后缀表达式为：\n");
    dispay(pqueue);


    int size=pqueue->size;      // 得到队列的大小
    printf("size=%d\n",size);


    while(pqueue->size!=0)      // 队列不为空,// pqueue->head->next!=pqueue->tail  pqueue->tail->prev!=pqueue->head;
    {
        D_Node *xx=pqueue->head->next;      // 队列的第一个节点
        if(xx->data.Is_num)     // 是操作数，直接压入操作数栈（链栈）
            push_num(ps2,xx->data.num);
        else
        {
            char c=xx->data.symblo;
            int n1=pop_num(ps2);    // 右操作数
            int n2=pop_num(ps2);    // 左操作数
            int n3;     // 存放算数结果
            if(is_low(c))
            {
                if(c=='+')
                    n3=n2+n1;
                else
                    n3=n2-n1;
            }
            else
            {
                if(c=='*')
                    n3=n2*n1;
                else
                    n3=n2/n1;
            }
            push_num(ps2,n3);
        }
        get_element(pqueue);        // 操作符直接出队，不入栈
    }
    int result=pop_num(ps2);        // 将栈顶（最后一个元素拿出），这就是该算数的结果

    // 这个栈不需要释放了。
    // 队列也不需要清空，因为它已经在出队时一个个释放了
    printf("结果为：%d\n",result);
    // free(ps1);
    
    free(ps2);
    free(aps);
    free(pqueue);
    return result;
}


